package com.common.utils;


import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;

/**
 */
public class OctalUtils {

    /**
     * 八进制转中文
     * @param dataStr 八进制字符
     * @return
     */
    public static String transfromOctalToString(String dataStr) {
        if (! dataStr.contains("\\")) {
            return dataStr;
        }
        //不属于八进制内容的字符
        StringBuilder oldBuffer = new StringBuilder();
        //属于八进制的内容，转成十六进制后缓存在这里
        StringBuilder hexBuffer = new StringBuilder();
        for (int i = 0; i < dataStr.length(); i ++) {
            char c = dataStr.charAt(i);
            if (c != '\\') {
                oldBuffer.append(c);
            }
            //反斜杠往后3个为一组，组成了一个八进制数。例如\20710,其实是207组成了一个八进制数
            else {
                char c1 = dataStr.charAt(i + 1);
                char c2 = dataStr.charAt(i + 2);
                char c3 = dataStr.charAt(i + 3);
                i += 3;
                //将八进制转换为十进制，再转换为十六进制
                String hex = Integer.toHexString((Integer.valueOf("" + c1 + c2 + c3, 8)));
                //先缓存住，直到凑够三个字节
                hexBuffer.append(hex);
                String hexString = hexBuffer.toString();
                //utf8编码中，三个字节为一个汉字
                if (hexString.length() == 6) {
                    //凑够三个字节了，转成汉字后放入oldBuffer中
                    oldBuffer.append(hexStr2Str(hexString));
                    //凑够一个汉字了，清空缓存
                    hexBuffer = new StringBuilder();
                }
            }
        }
        return oldBuffer.toString();
    }
    /**
     * 十六进制转换字符串
     */
    private static String hexStr2Str(String hexStr) {
        String str = "0123456789abcdef";
        char[] hexs = hexStr.toCharArray();
        byte[] bytes = new byte[hexStr.length() / 2];
        int n;
        for (int i = 0; i < bytes.length; i++) {
            n = str.indexOf(hexs[2 * i]) * 16;
            n += str.indexOf(hexs[2 * i + 1]);
            bytes[i] = (byte) (n & 0xff);
        }
        return new String(bytes, StandardCharsets.UTF_8);
    }

    /**
     * 中文转八进制字符
     * @param s
     * @return
     */
    public static String toOct(String s)
    {
        String result = "";
        byte[] bytes = s.getBytes();
        for (byte b : bytes)
        {
            int b1 = b;
            if (b1 < 0) {
                b1 = 256 + b1;
            }
            result += "\\" + (b1 / 64) % 8 +  "" + (b1 / 8) % 8 + "" + b1 % 8;
        }
        return result;
    }

    /**
     * 八进制字符转中文
     *  只转换并显示属于八进制的字符(\\xxx形式)
     * @param s
     * @return
     */
    public static String getOct(String s) {
        String[] as = s.split("\\\\");
        byte[] arr = new byte[as.length - 1];
        for (int i = 1; i < as.length; i++)
        {
            int sum = 0;
            int base = 64;
            for (char c : as[i].toCharArray())
            {
                sum += base * ((int)c - '0');
                base /= 8;
            }
            if (sum >= 128) {
                sum = sum - 256;
            }
            arr[i - 1] = (byte)sum;
        }
        String getOctStr = null;
        try {
            getOctStr = new String(arr, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return getOctStr; //如果还有乱码，这里编码方式你可以修改下，比如试试看unicode gbk等等
    }

//https://blog.csdn.net/qq_43223477/article/details/119390530?spm=1001.2101.3001.6650.6&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6.pc_relevant_antiscanv2&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7EBlogCommendFromBaidu%7ERate-6.pc_relevant_antiscanv2&utm_relevant_index=13
    public static void main(String[] args) {
        //weihushijian5xiaoshi
        String s = "\\345\\215\\201\\345\\244\\232\\351\\246\\226\\346\\235\\245";//维护时间5小时
        System.out.println("transfromOctalToString(s) = " + transfromOctalToString(s));//transfromOctalToString(s) = 维护时间5小时
        System.out.println("getOct(s) = " + getOct(s));//getOct(s) = 维护时间小时
        System.out.println("toOct(\"小时\") = " + toOct("小时"));//toOct("维护") = \345\260\217\346\227\266
    }
}

